package com.ffz.calcitesql.demo;

/* * Copyright © 2023 https://www.cestc.cn/ All rights reserved. */

import org.apache.calcite.avatica.util.Casing;
import org.apache.calcite.sql.SqlIdentifier;
import org.apache.calcite.sql.SqlNode;
import org.apache.calcite.sql.SqlNodeList;
import org.apache.calcite.sql.SqlOrderBy;
import org.apache.calcite.sql.SqlSelect;
import org.apache.calcite.sql.SqlWriterConfig;
import org.apache.calcite.sql.dialect.OracleSqlDialect;
import org.apache.calcite.sql.parser.SqlParseException;
import org.apache.calcite.sql.parser.SqlParser;
import org.apache.calcite.sql.parser.impl.SqlParserImpl;
import org.apache.calcite.sql.pretty.SqlPrettyWriter;
import org.apache.calcite.sql.util.SqlShuttle;
import org.apache.calcite.sql.validate.SqlConformanceEnum;

/**
 * Sql解析Demo.
 *
 * @author fengfazheng
 * @since 2024/1/11 18:45
 */
public class CalciteParserDemo {
    public static void main(String[] args) throws SqlParseException {
//        String sql="select * from emps where id=1";
        String sql3 = "select  dt.d_year \n" +
                "       ,item.i_brand_id brand_id \n" +
                "       ,item.i_brand brand\n" +
                "       ,sum(ss_sales_price) sum_agg\n" +
                " from  date_dim dt \n" +
                "      ,store_sales\n" +
                "      ,item\n" +
                " where dt.d_date_sk = store_sales.ss_sold_date_sk\n" +
                "   and store_sales.ss_item_sk = item.i_item_sk\n" +
                "   and item.i_manufact_id = 816\n" +
                "   and dt.d_moy=11\n" +
                " group by dt.d_year\n" +
                "      ,item.i_brand\n" +
                "      ,item.i_brand_id\n" +
                " order by dt.d_year\n" +
                "         ,sum_agg desc\n" +
                "         ,brand_id\n" +
                " limit 100";
        // 生成SQL解析配置
        SqlParser.Config config = SqlParser.config()
                .withParserFactory(SqlParserImpl.FACTORY)
                .withUnquotedCasing(Casing.UNCHANGED)
                .withQuotedCasing(Casing.UNCHANGED)
                .withCaseSensitive(false)
                .withConformance(SqlConformanceEnum.MYSQL_5);
        // 创建一个SQL解析器
        SqlParser sqlParser = SqlParser.create(sql3, config);
        // 执行SQL解析
        SqlNode sqlNode = sqlParser.parseQuery();
        System.out.println(sqlNode);
        SqlOrderBy sqlOrderBy=(SqlOrderBy)sqlNode;
        // 获取 SELECT 中的字段列表
        SqlSelect sqlSelect = (SqlSelect)sqlOrderBy.query;
        SqlNodeList selectList = sqlSelect.getSelectList();
        selectList.accept(new SqlShuttle() {
            @Override
            public SqlNode visit(SqlIdentifier id) {
                System.out.println("Column: " + id.toString());
                return id;
            }
        });

        // 获取 FROM 子句中的表名
//        SqlNode from = sqlOrderBy.getFrom();
//        if (from instanceof SqlIdentifier) {
//            SqlIdentifier fromIdentifier = (SqlIdentifier) from;
//            System.out.println("Table: " + fromIdentifier.toString());
//        }
    }
//        System.out.println(sqlNode);
    // 输出SQL配置
//        SqlWriterConfig sqlWriterConfig = SqlPrettyWriter.config()
//                .withAlwaysUseParentheses(true)
//                .withUpdateSetListNewline(false)
//                .withQuoteAllIdentifiers(true)
//                .withFromFolding(SqlWriterConfig.LineFolding.TALL)
//                .withIndentation(0)
//                .withKeywordsLowerCase(false)
//                .withDialect(OracleSqlDialect.DEFAULT);
    // 将SqlNode 输出为某个引擎的SQL
//        System.out.println(sqlNode.toSqlString(c->sqlWriterConfig));
}

